<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<title>Programs</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
		<meta name="viewport" content="width=device-width initial-scale=1">
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<meta http-equiv="Content-Language" content="en-gb">

<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
		
	</head>
	<body class="commentary-font">
		<nav role="navigation">
		<h1><a href="../index.html"><img src="../docs-assets/Inform.png" height=72> </a></h1>
<ul><li><a href="../index.html">home</a></li>
</ul><h2>Compiler</h2><ul>
<li><a href="../structure.html">structure</a></li>
<li><a href="../inbuildn.html">inbuild</a></li>
<li><a href="../inform7n.html">inform7</a></li>
<li><a href="../intern.html">inter</a></li>
<li><a href="../services.html">services</a></li>
<li><a href="../secrets.html">secrets</a></li>
</ul><h2>Other Tools</h2><ul>
<li><a href="../inblorbn.html">inblorb</a></li>
<li><a href="../inform6.html">inform6</a></li>
<li><a href="../inpolicyn.html">inpolicy</a></li>
</ul><h2>Resources</h2><ul>
<li><a href="../extensions.html">extensions</a></li>
<li><a href="../kits.html">kits</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inform"><img src="../docs-assets/github.png" height=0> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=0> inweb</a></li>
<li><a href="https://github.com/ganelson/intest"><img src="../docs-assets/github.png" height=0> intest</a></li>
</ul>
		</nav>
		<main role="main">
		<!-- Weave of 'Programs' generated by inweb -->
<div class="breadcrumbs">
    <ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="../extensions.html">Kits</a></li><li><a href="index.html">DialogueKit</a></li><li><b>Programs</b></li></ul></div>
<p class="purpose">Programs  How dialogue beat programs are stored and interpreted.</p>

<ul class="toc"><li><a href="prgrm.html#SP1">&#167;1. D-code</a></li><li><a href="prgrm.html#SP2">&#167;2. Containment</a></li><li><a href="prgrm.html#SP3">&#167;3. Disassembly</a></li><li><a href="prgrm.html#SP4">&#167;4. The D-stack</a></li><li><a href="prgrm.html#SP5">&#167;5. Reading the current choice list</a></li><li><a href="prgrm.html#SP6">&#167;6. Tracing the stack</a></li><li><a href="prgrm.html#SP7">&#167;7. Pushing and popping</a></li><li><a href="prgrm.html#SP8">&#167;8. Flow operations</a></li><li><a href="prgrm.html#SP9">&#167;9. Main interpreter loop</a></li><li><a href="prgrm.html#SP10">&#167;10. The line instruction</a></li><li><a href="prgrm.html#SP11">&#167;11. The decision instruction</a></li><li><a href="prgrm.html#SP12">&#167;12. Listing choices for a decision</a></li><li><a href="prgrm.html#SP13">&#167;13. Dealing with action choices</a></li><li><a href="prgrm.html#SP14">&#167;14. Exercising a choice</a></li></ul><hr class="tocbar">

<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. D-code.</b>Each dialogue beat contains a program which lays out the structure of its lines
and choices. This program is stored in a simple bytecode which we'll call "D-code",
for the sake of giving it a name, though it is very rudimentary and would not
even be Turing-complete except for the ability to apply conditions and state
changes by "now" and "if" side-effects.
</p>

<p class="commentary">A program consists of a sequence of 0 or more two-word instructions terminated
by the word 0. Each instruction has an opcode word followed by an operand word.
The opcode word is encoded as <span class="extract"><span class="extract-syntax">100*I + D</span></span>, where <span class="extract"><span class="extract-syntax">I</span></span> is an instruction code
ranging from 1 upwards, and <span class="extract"><span class="extract-syntax">D</span></span> is the depth within the dialogue tree, ranging
from 0 upwards. Finding 0 in the opcode word position therefore unambiguously
marks the end, since <span class="extract"><span class="extract-syntax">I</span></span> cannot be 0 even though <span class="extract"><span class="extract-syntax">D</span></span> can.
</p>

<p class="commentary">Depth levels correspond to the tree structure in the original dialogue. This
is not quite the same as the number of tab stops in the source code because
Inform regroups choice nodes under decision nodes (one for each decision to
be taken), which are implicit in the source text, and therefore don't appear
in the tab indentation. This effectively pushes all choice nodes out by 1
in depth, compared to the tab indentation level, each time a nested decision
is reached.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">D</span></span> begins at 0, is never negative, and is never more than 1 greater than the
previous instruction. The Inform compiler never generates <span class="extract"><span class="extract-syntax">D</span></span> values greater
than about 25 (see <a href="../if-module/6-dn.html" class="internal">Dialogue Nodes (in if)</a>), so there is no danger of <span class="extract"><span class="extract-syntax">D</span></span>
reaching 100 and corrupting the <span class="extract"><span class="extract-syntax">I</span></span> value.
</p>

<p class="commentary">There are only three instruction codes:
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">LINE_DCODEI</span></span> means a dialogue line, and the operand then represents the
enumerated value for the dialogue line.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span> similarly represents a choice. All such instructions are
immediate children of a <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> instruction.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> is a decision point, and the operand is the "decision type",
one of the <span class="extract"><span class="extract-syntax">*_DCODEDT</span></span> values. All immediate children of a <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span>
instruction are <span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span>s.
</p>

<ul class="items"><li>&#9679; <span class="extract"><span class="extract-syntax">BLANK_DCODEDT</span></span> should never appear in compiled D-code, and is only used
in the Inform compiler.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">TEXTUAL_DCODEDT</span></span> is a decision point offering textual choices for the
player to pick.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">PARSED_COMMAND_DCODEDT</span></span> is a decision point requiring us to wait for the
next typed command and see what action it produced.
</li><li>&#9679; <span class="extract"><span class="extract-syntax">FLOW_DCODEDT</span></span> is a flow control choice, <span class="extract"><span class="extract-syntax">-&gt;</span></span> or <span class="extract"><span class="extract-syntax">&lt;-</span></span>.
</li></ul>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>

<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">BLANK_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">TEXTUAL_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">PARSED_COMMAND_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">3</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">FLOW_DCODEDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">RANDOMISED_CONTROL_DDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">5</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">SHUFFLE_CONTROL_DDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">6</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">CYCLE_CONTROL_DDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">7</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">STEP_CONTROL_DDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">8</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">STEP_STOP_CONTROL_DDT</span><span class="plain-syntax"> = </span><span class="constant-syntax">9</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. Containment.</b>This enables us to implement the test for whether a given line or choice
occurs in a beat, because we need only look to see whether it occurs as
operand in the instructions for the beat's program.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorTestContainment(dl, db, DIALOGUE_LINE_TY, DIALOGUE_BEAT_TY)</span></span> tests
whether the line <span class="extract"><span class="extract-syntax">dl</span></span> occurs in the beat <span class="extract"><span class="extract-syntax">db</span></span>, returning <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorTestContainment(dc, db, DIALOGUE_CHOICE_TY, DIALOGUE_BEAT_TY)</span></span> tests
whether the choice <span class="extract"><span class="extract-syntax">dc</span></span> occurs in the beat <span class="extract"><span class="extract-syntax">db</span></span>, returning <span class="extract"><span class="extract-syntax">true</span></span> or <span class="extract"><span class="extract-syntax">false</span></span>.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorTestContainment</span><span class="plain-syntax"> </span><span class="identifier-syntax">X</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">tX</span><span class="plain-syntax"> </span><span class="identifier-syntax">tb</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">wanted</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tb</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Not a db ***"</span><span class="plain-syntax">; </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tX</span><span class="plain-syntax"> ~= </span><span class="identifier-syntax">DIALOGUE_LINE_TY</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Not a dl/dc ***"</span><span class="plain-syntax">; </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">tX</span><span class="plain-syntax"> == </span><span class="identifier-syntax">DIALOGUE_LINE_TY</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">X</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_DIALOGUE_LINES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wanted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">X</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">1</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">X</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_DIALOGUE_CHOICES</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">wanted</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> == </span><span class="identifier-syntax">wanted</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1) == </span><span class="identifier-syntax">X</span><span class="plain-syntax">)) </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorBeatOpeningLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</span><span class="plain-syntax">)) </span><span class="string-syntax">"*** no beat ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> == </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="string-syntax">"*** no line ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. Disassembly.</b>Purely for debugging purposes:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDisassemble</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &lt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">db</span><span class="plain-syntax"> &gt; </span><span class="identifier-syntax">NO_DIALOGUE_BEATS</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">db</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" ("</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatAvailable</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"available"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unavailable"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">", "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatRelevant</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"relevant"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"irrelevant"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">", "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorBeatAccessible</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">player</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"accessible"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"inaccessible"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">", "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"performed"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unperformed"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">", "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">recurring</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"recurring"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"non-recurring"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">", "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_BEAT_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">db</span><span class="plain-syntax">, </span><span class="identifier-syntax">spontaneous</span><span class="plain-syntax">)) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"spontaneous"</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"unspontaneous"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"):^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">db</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">program</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">which</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1));</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=0: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">depth</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"  "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax">(</span><span class="identifier-syntax">which</span><span class="plain-syntax">, </span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">which</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">which</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"LINE "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueLineName</span><span class="plain-syntax">) </span><span class="identifier-syntax">operand</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"CHOICE "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueChoiceName</span><span class="plain-syntax">) </span><span class="identifier-syntax">operand</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"DECISION of type "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">operand</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">TEXTUAL_DCODEDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"TEXTUAL"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">PARSED_COMMAND_DCODEDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"PARSED"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">FLOW_DCODEDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"FLOW"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">RANDOMISED_CONTROL_DDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"RANDOMISED"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">SHUFFLE_CONTROL_DDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"SHUFFLE"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">CYCLE_CONTROL_DDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"CYCLE"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">STEP_CONTROL_DDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"STEP"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">STEP_STOP_CONTROL_DDT</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"STEP_STOP"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">default</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Unknown ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">default</span><span class="plain-syntax">: </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Unimplemented ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>&#167;4. The D-stack.</b>The interpreter for D-code has to perform beats (and therefore their programs)
in a way which can easily nest, since one beat can call for another to be
performed and then continue. Moreover, it also sometimes calls itself to
interpret just a subtree from a full program. Either way, it needs to keep
its state on a stack so that it can safely interrupt what it's doing, call
itself, and then resume where it left off. The stack consists of a suite of
arrays, as follows:
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackBeat</span></span> holds the beat whose program is being interpreted.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackPC</span></span> holds the current PC ("program counter"), which counts in
words from the start of the program, which is position 0. It therefore
increases by 2 to advance by one instruction.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackMin</span></span> holds the minimum instruction level for the subtree
being interpreted. If the whole tree is being interpreted, this is 0.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackStart</span></span> is a flag which is true if and only if the current
subtree was the entire tree, so that execution began from PC 0.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackDecisionPC</span></span> holds the PC position of the last instruction
node of <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> type, that is, the last decision; or -1 if no
decision node has been reached in this subtree yet.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastPC</span></span> holds the PC position before the most recent
instruction was executed, or 0 if none has yet been executed.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackChoices</span></span> holds a valid Inform list, which in turn holds the
set of choices in the current decision. If no decision has been reached in
the execution of the subtree, the list is empty.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastSpeaker</span></span> holds the identity of the last person/object to
be the speaker in a line which was actually performed (and note that not
all <span class="extract"><span class="extract-syntax">LINE_DCODEI</span></span> instructions result in a performance). It is <span class="extract"><span class="extract-syntax">nothing</span></span>
if no line has been performed in (this performance of) the current beat,
except perhaps for narration.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorStackLastInterlocutor</span></span> similarly holds the identity of the interlocutor
for that line. It is <span class="extract"><span class="extract-syntax">nothing</span></span> if no line has been performed in (this performance
of) the current beat, except perhaps for narration, or if the most recently
performed line had no interlocutor.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">Constant</span><span class="plain-syntax"> </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax"> = </span><span class="constant-syntax">20</span><span class="plain-syntax">;</span>

<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastSpeaker</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
<span class="reserved-syntax">Array</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackLastInterlocutor</span><span class="plain-syntax"> --&gt; </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">;</span>
</pre>
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>&#167;5. Reading the current choice list.</b>The stack begins empty, except that we arrange for there always to be a
valid Inform list in <span class="extract"><span class="extract-syntax">DirectorStackChoices--&gt;0</span></span>, so that if the phrase
"current choice list" is used at a time when no dialogue has ever run, it will
still produce an empty list in a typesafe way.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorCurrentChoiceList</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;0 == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;0 = </span><span class="identifier-syntax">CreatePV</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;0, </span><span class="identifier-syntax">LIST_ITEM_KOV_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;0;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>&#167;6. Tracing the stack.</b>For debugging only, of course.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"["</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax">=0: </span><span class="identifier-syntax">j</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">: </span><span class="identifier-syntax">j</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">j</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" --&gt; "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"$"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == -1) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"+return"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"[*"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="string-syntax">"]"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"+"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">, </span><span class="string-syntax">" "</span><span class="plain-syntax">, </span><span class="string-syntax">"L"</span><span class="plain-syntax">, </span><span class="identifier-syntax">depth</span><span class="plain-syntax">, </span><span class="string-syntax">"/"</span><span class="plain-syntax">, </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">, </span><span class="string-syntax">" "</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DirectorDisassembleInstruction</span><span class="plain-syntax">(</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">, </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1));</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">" {"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LIST_OF_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">j</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"}"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"]^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"[Director stack empty]^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>&#167;7. Pushing and popping.</b>Two functions exist to create a new "subtree stack frame", pushing, or to destroy
an existing one, popping the stack.
</p>

<p class="commentary"><span class="extract"><span class="extract-syntax">DirectorPush</span></span> must specify the beat, the minimum instruction level to
execute (by default 0), and the initial pc (position in the program) to execute
from (by default 0). Within such a subtree, the D-code interpreter will run
from the PC position until it hits an instruction of too low a level, or until
it hits the end of the program. Thus, it can execute either the entire
dialogue tree, or any well-formed subtree of it.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorPush</span><span class="plain-syntax"> </span><span class="identifier-syntax">db</span><span class="plain-syntax"> </span><span class="identifier-syntax">min</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_flag</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">MAX_BEAT_PERFORMANCE_NESTING</span><span class="plain-syntax">)</span>
<span class="plain-syntax">        </span><span class="string-syntax">"*** Director stack overflow: too many open beats ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">db</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">min</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackLastSpeaker</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorStackLastInterlocutor</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="reserved-syntax">nothing</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CreatePV</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">WritePVField</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">, </span><span class="identifier-syntax">LIST_ITEM_KOV_F</span><span class="plain-syntax">, </span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Push to: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Pop to: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>&#167;8. Flow operations.</b><span class="extract"><span class="extract-syntax">DirectorAgain</span></span> implements the flow marker <span class="extract"><span class="extract-syntax">&lt;-</span></span>; <span class="extract"><span class="extract-syntax">DirectorStop</span></span> implements <span class="extract"><span class="extract-syntax">-&gt; stop</span></span>.
Both involve popping, either back to the last decision point (which means adjusting
the PC as well) or to the last time a new beat began.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorAgain</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- again at: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">1</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;0 = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorStop</span><span class="plain-syntax"> </span><span class="identifier-syntax">enough</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">enough</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorStackStart</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) </span><span class="identifier-syntax">enough</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">enough</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>&#167;9. Main interpreter loop.</b>Calling <span class="extract"><span class="extract-syntax">DirectorRun()</span></span> lets the interpreter rip, running until the end of the
current subtree, or some catastrophe happened, or we need to wait for the player
to enter a command into the command parser. (In the latter case we can resume
where we left off with just by calling <span class="extract"><span class="extract-syntax">DirectorRun()</span></span> again.)
</p>

<p class="commentary">Note that this loop should never hit a <span class="extract"><span class="extract-syntax">CHOICE_DCODEI</span></span> instruction, because
those are always underneath <span class="extract"><span class="extract-syntax">DECISION_DCODEI</span></span> instructions &mdash; which it does hit.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> </span><span class="identifier-syntax">operand_at</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> </span><span class="identifier-syntax">sc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="reserved-syntax">true</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_is_paused_for_command</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="comment-syntax">There must be a program</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="comment-syntax">The story must not have finished</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">deadflag</span><span class="plain-syntax">) { </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>

<span class="plain-syntax">        </span><span class="comment-syntax">If there are choices to be made, we have to wait for the command</span>
<span class="plain-syntax">        </span><span class="comment-syntax">input loop and some sort of action to be generated, so return for now</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="comment-syntax">If the beat is tied to a scene and the scene has itself finished for</span>
<span class="plain-syntax">        </span><span class="comment-syntax">unrelated reasons, end the beat now</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">sc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetScene</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">sc</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">scene_status</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">sc</span><span class="plain-syntax"> - </span><span class="constant-syntax">1</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">)) { </span><span class="identifier-syntax">DirectorStop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>

<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == -1) { </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="comment-syntax">Fetch and decode the next instruction</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">operand_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">operand</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">operand_at</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) { </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">depth</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) { </span><span class="identifier-syntax">DirectorPop</span><span class="plain-syntax">(); </span><span class="reserved-syntax">return</span><span class="plain-syntax">; }</span>

<span class="plain-syntax">        </span><span class="comment-syntax">Advance the PC to the next instruction to be read after this one, or</span>
<span class="plain-syntax">        </span><span class="comment-syntax">to -1 if there is no next instruction in the current subtree</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 &gt; </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = -1;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100) &lt; </span><span class="identifier-syntax">DirectorStackMin</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1)) </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = -1;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Instruction ("</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pc</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"next is "</span><span class="plain-syntax">, </span><span class="identifier-syntax">pc</span><span class="plain-syntax">; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"last"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"): "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        }</span>

<span class="plain-syntax">        </span><span class="comment-syntax">Store the next PC position</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorStackPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">pc</span><span class="plain-syntax">;</span>

<span class="plain-syntax">        </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">instruction</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LINE_DCODEI</span><span class="plain-syntax">:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">line_performance_count</span><span class="plain-syntax">++;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DirectorExecuteLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DECISION_DCODEI</span><span class="plain-syntax">:</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DirectorStackDecisionPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1) = </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">operand_at</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">operand_at</span><span class="plain-syntax">)%100 +</span>
<span class="plain-syntax">                    </span><span class="constant-syntax">100</span><span class="plain-syntax">*(</span><span class="identifier-syntax">DirectorExecuteDecision</span><span class="plain-syntax">(</span><span class="identifier-syntax">operand</span><span class="plain-syntax">%100, </span><span class="identifier-syntax">operand</span><span class="plain-syntax">/100));</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">:</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** Encountered CHOICE_DCODEI ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">default</span><span class="plain-syntax">: </span><span class="string-syntax">"*** Bad D-code instruction ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>&#167;10. The line instruction.</b>This tries to perform the given line, and if it succeeds, then executes the
subtree beneath it; the first node of which will be the next instruction in
the program if and only if that has depth greater by 1 than the current node.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExecuteLine</span><span class="plain-syntax"> </span><span class="identifier-syntax">dl</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">)%100;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorPerformLine</span><span class="plain-syntax">(</span><span class="identifier-syntax">dl</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">+2);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">next_instruction</span><span class="plain-syntax"> % </span><span class="constant-syntax">100</span><span class="plain-syntax"> == </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorPush</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1, </span><span class="identifier-syntax">last_pc</span><span class="plain-syntax">+2);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>&#167;11. The decision instruction.</b>The immediate children of the instruction will all be choice instructions, and
the first task is to obtain them. If there are none, there's nothing to decide
and we silently return.
</p>

<p class="commentary">We deal with <span class="extract"><span class="extract-syntax">TEXTUAL_DCODEDT</span></span> and <span class="extract"><span class="extract-syntax">FLOW_DCODEDT</span></span> decisions immediately, and
empty the choices list as soon as we can. Perhaps surprisingly, we do nothing
at all about a <span class="extract"><span class="extract-syntax">PARSED_COMMAND_DCODEDT</span></span> except to signal a sort of exception.
This function call nevertheless has an effect because it leaves the choices list
on the stack, where it will cause the D-code interpreter to halt waiting for a
command, to be re-entered later on when actions are processed.
</p>

<p class="commentary">This function is passed a state value, and must return it (even if unchanged).
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="identifier-syntax">Global</span><span class="plain-syntax"> </span><span class="identifier-syntax">dialogue_selection_value</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExecuteDecision</span><span class="plain-syntax"> </span><span class="identifier-syntax">decision</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">count</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> </span><span class="identifier-syntax">m</span><span class="plain-syntax"> </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax"> </span><span class="identifier-syntax">k</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorListChoices</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">count</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- no available options^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">decision</span><span class="plain-syntax"> == </span><span class="constant-syntax">2</span><span class="plain-syntax"> </span><span class="reserved-syntax">or</span><span class="plain-syntax"> </span><span class="constant-syntax">3</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- available options: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">LIST_OF_TY_Say</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">); </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">count</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">decision</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">TEXTUAL_DCODEDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dialogue_selection_value</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DivideParagraphPoint</span><span class="plain-syntax">();</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="string-syntax">"*** no activity ***"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">BeginActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">ForActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</span><span class="plain-syntax">)) &amp;&amp;</span>
<span class="plain-syntax">                    (</span><span class="identifier-syntax">RulebookFailed</span><span class="plain-syntax">())) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">EndActivity</span><span class="plain-syntax">(</span><span class="identifier-syntax">OFFERING_A_DIALOGUE_CHOICE</span><span class="plain-syntax">, </span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="comment-syntax">DivideParagraphPoint();</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dialogue_selection_value</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">PARSED_COMMAND_DCODEDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">director_is_paused_for_command</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">FLOW_DCODEDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorFollowFlowMarker</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">RANDOMISED_CONTROL_DDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="reserved-syntax">random</span><span class="plain-syntax">(</span><span class="identifier-syntax">count</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">SHUFFLE_CONTROL_DDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">n</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">n</span><span class="plain-syntax">++)</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">DirectorWriteChoiceState</span><span class="plain-syntax">(</span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">), </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">count</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">m</span><span class="plain-syntax"> = </span><span class="reserved-syntax">random</span><span class="plain-syntax">(</span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax">--; </span><span class="identifier-syntax">state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">n</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">count</span><span class="plain-syntax">: </span><span class="identifier-syntax">n</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorReadChoiceState</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">m</span><span class="plain-syntax">--;</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">m</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">DirectorWriteChoiceState</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                        </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                        </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                    }</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">CYCLE_CONTROL_DDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">count</span><span class="plain-syntax">) </span><span class="identifier-syntax">n</span><span class="plain-syntax">++; </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">STEP_CONTROL_DDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">count</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">n</span><span class="plain-syntax">++; </span><span class="identifier-syntax">state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">STEP_STOP_CONTROL_DDT</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">n</span><span class="plain-syntax"> = </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">n</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">count</span><span class="plain-syntax">) { </span><span class="identifier-syntax">n</span><span class="plain-syntax">++; </span><span class="identifier-syntax">state</span><span class="plain-syntax"> = </span><span class="identifier-syntax">n</span><span class="plain-syntax">; }</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">n</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">default</span><span class="plain-syntax">:</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"*** unimplemented dtd "</span><span class="plain-syntax">, </span><span class="identifier-syntax">decision</span><span class="plain-syntax">, </span><span class="string-syntax">" ***^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">state</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>&#167;12. Listing choices for a decision.</b>This finds all of the unperformed or recurring choices which are currently
available to a given decision node, making them the content of an Inform list.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorListChoices</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">fn</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">depth</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 &gt; </span><span class="identifier-syntax">depth</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)%100 == </span><span class="identifier-syntax">depth</span><span class="plain-syntax">+1) &amp;&amp; ((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">)/100 == </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">pc</span><span class="plain-syntax">+1);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) ||</span>
<span class="plain-syntax">                    (</span><span class="identifier-syntax">GProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">recurring</span><span class="plain-syntax">))) &amp;&amp;</span>
<span class="plain-syntax">                (</span><span class="identifier-syntax">DirectorChoiceAvailable</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">)))</span>
<span class="plain-syntax">                </span><span class="identifier-syntax">LIST_OF_TY_InsertItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>&#167;13. Dealing with action choices.</b>At various stages in action processing, the main story loop calls the following
three functions, which in turn call <span class="extract"><span class="extract-syntax">DirectorDetectActionChoice</span></span>. That looks
for a match of the current action against one of the choices in the list on
the stack: it then re-enters the D-code interpreter if it makes a match, and
eventually comes back with <span class="extract"><span class="extract-syntax">true</span></span> to halt action processing. If it makes no
match, it returns <span class="extract"><span class="extract-syntax">false</span></span>.
</p>

<p class="commentary">Note that if we do make a match, and try to resume dialogue, we may still not
be able to complete it and empty the D-stack, because it may pause again for
a further action choice. But that's okay, because action processing is nested
too, even if the VM stack does for a while have a surprising state.
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorBeforeAction</span><span class="plain-syntax">;  </span><span class="identifier-syntax">director_is_paused_for_command</span><span class="plain-syntax"> = </span><span class="reserved-syntax">false</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">BEFORE_DSEL</span><span class="plain-syntax">);     ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorInsteadAction</span><span class="plain-syntax">; </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">INSTEAD_OF_DSEL</span><span class="plain-syntax">); ];</span>
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorAfterAction</span><span class="plain-syntax">;   </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">AFTER_DSEL</span><span class="plain-syntax">);      ];</span>

<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorDetectActionChoice</span><span class="plain-syntax"> </span><span class="identifier-syntax">stage</span><span class="plain-syntax"> </span><span class="identifier-syntax">N</span><span class="plain-syntax"> </span><span class="identifier-syntax">list</span><span class="plain-syntax"> </span><span class="identifier-syntax">was</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> </span><span class="identifier-syntax">fn</span><span class="plain-syntax"> </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> </span><span class="identifier-syntax">cht</span><span class="plain-syntax"> </span><span class="identifier-syntax">echt</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_otherwise</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_is_paused_for_command</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">list</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackChoices</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">N</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">N</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>

<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- found: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">echt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">AFTER_DSEL</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">i</span><span class="plain-syntax">=1: </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;=</span><span class="identifier-syntax">N</span><span class="plain-syntax">: </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">LIST_OF_TY_GetItem</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">cht</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorChoiceType</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">        </span><span class="comment-syntax">print "Stage ", stage, " choice ", i, "/", N, " cht ", cht, " echt ", echt, "^";</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">cht</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">echt</span><span class="plain-syntax">) </span><span class="identifier-syntax">echt</span><span class="plain-syntax"> = </span><span class="identifier-syntax">cht</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">cht</span><span class="plain-syntax"> == </span><span class="identifier-syntax">OTHERWISE_DSEL</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">stage</span><span class="plain-syntax"> &gt;= </span><span class="identifier-syntax">echt</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">suppress_otherwise</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dc</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="identifier-syntax">fn</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorChoiceRawContent</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">fn</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">fn</span><span class="plain-syntax">())) {</span>
<span class="plain-syntax">                </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorChoiceType</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">) == </span><span class="identifier-syntax">stage</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">                    </span><span class="identifier-syntax">chose</span><span class="plain-syntax"> = </span><span class="identifier-syntax">dc</span><span class="plain-syntax">; </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">                    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">DirectorChoiceType</span><span class="plain-syntax">(</span><span class="identifier-syntax">dc</span><span class="plain-syntax">) ~= </span><span class="identifier-syntax">stage</span><span class="plain-syntax">) </span><span class="identifier-syntax">suppress_otherwise</span><span class="plain-syntax"> = </span><span class="reserved-syntax">true</span><span class="plain-syntax">;</span>
<span class="plain-syntax">                }</span>
<span class="plain-syntax">            }</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chose</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- selected "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueChoiceName</span><span class="plain-syntax">) </span><span class="identifier-syntax">chose</span><span class="plain-syntax">, </span><span class="string-syntax">" at stage "</span><span class="plain-syntax">, </span><span class="identifier-syntax">stage</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- no selection at stage "</span><span class="plain-syntax">, </span><span class="identifier-syntax">stage</span><span class="plain-syntax">, </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chose</span><span class="plain-syntax"> == </span><span class="reserved-syntax">false</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">2</span><span class="plain-syntax">) { </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- gave up: "</span><span class="plain-syntax">; </span><span class="identifier-syntax">DirectorTraceStack</span><span class="plain-syntax">(); }</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">rfalse</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>

<span class="plain-syntax">    </span><span class="identifier-syntax">LIST_OF_TY_SetLength</span><span class="plain-syntax">(</span><span class="identifier-syntax">list</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax">(</span><span class="identifier-syntax">chose</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">was</span><span class="plain-syntax"> = </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">debug_dialogue</span><span class="plain-syntax">) {</span>
<span class="plain-syntax">            </span><span class="reserved-syntax">print</span><span class="plain-syntax"> </span><span class="string-syntax">"-- Resuming "</span><span class="plain-syntax">, (</span><span class="identifier-syntax">PrintDialogueBeatName</span><span class="plain-syntax">) </span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), </span><span class="string-syntax">"^"</span><span class="plain-syntax">;</span>
<span class="plain-syntax">        }</span>
<span class="plain-syntax">        </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax">();</span>
<span class="plain-syntax">        </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">was</span><span class="plain-syntax"> == </span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    }</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">rtrue</span><span class="plain-syntax">;</span>
<span class="plain-syntax">];</span>
</pre>
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>&#167;14. Exercising a choice.</b>By whatever means, then, a choice <span class="extract"><span class="extract-syntax">dc</span></span> has been made in either the textual or
action-based sense, and the following function runs the D-code interpreter
on the subtree underneath it:
</p>

<pre class="displayed-code all-displayed-code code-font">
<span class="plain-syntax">[ </span><span class="identifier-syntax">DirectorExerciseChoice</span><span class="plain-syntax"> </span><span class="identifier-syntax">dc</span><span class="plain-syntax"> </span><span class="identifier-syntax">program</span><span class="plain-syntax"> </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> </span><span class="identifier-syntax">spc</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">WriteGProperty</span><span class="plain-syntax">(</span><span class="identifier-syntax">DIALOGUE_CHOICE_TY</span><span class="plain-syntax">, </span><span class="identifier-syntax">dc</span><span class="plain-syntax">, </span><span class="identifier-syntax">performed</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">program</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorBeatGetProgram</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1));</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">DirectorStackLastPC</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">pc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (((</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">spc</span><span class="plain-syntax">)/100 ~= </span><span class="identifier-syntax">CHOICE_DCODEI</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">spc</span><span class="plain-syntax">+1) ~= </span><span class="identifier-syntax">dc</span><span class="plain-syntax">)) </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> = </span><span class="identifier-syntax">spc</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">;</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorPush</span><span class="plain-syntax">(</span><span class="identifier-syntax">DirectorStackBeat</span><span class="plain-syntax">--&gt;(</span><span class="identifier-syntax">director_sp</span><span class="plain-syntax">-1), (</span><span class="identifier-syntax">program</span><span class="plain-syntax">--&gt;</span><span class="identifier-syntax">pc</span><span class="plain-syntax">) % </span><span class="constant-syntax">100</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">, </span><span class="identifier-syntax">spc</span><span class="plain-syntax">);</span>
<span class="plain-syntax">    </span><span class="identifier-syntax">DirectorRun</span><span class="plain-syntax">();</span>
<span class="plain-syntax">];</span>
</pre>
<nav role="progress"><div class="progresscontainer">
    <ul class="progressbar"><li class="progressprev"><a href="chcs.html">&#10094;</a></li><li class="progresssection"><a href="drctr.html">drctr</a></li><li class="progresssection"><a href="bts.html">bts</a></li><li class="progresssection"><a href="lns.html">lns</a></li><li class="progresssection"><a href="chcs.html">chcs</a></li><li class="progresscurrent">prgrm</li><li class="progressnextoff">&#10095;</li></ul></div>
</nav><!-- End of weave -->

		</main>
	</body>
</html>

